iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Modern Web

雙向奔赴的websocket與冰冷的react系列 第 27

[day27]WebSocket 與 React 的狀態管理:實時更新數據(時鐘)

  • 分享至 

  • xImage
  •  

在現代的網頁應用中,實時更新數據已經成為一種常見的需求,例如即時聊天、實時數據分析等。WebSocket 提供了在客戶端和服務器之間進行全雙工通信的能力,使得我們可以實現實時數據的傳輸。接下來會使用 WebSocket,並結合 React 的狀態管理來實時更新數據。

接下來做一個已後端時間為主的時鐘

本次目標:

  • 建立 WebSocket 連接:在 React 應用中建立與服務器的 WebSocket 連接。
  • 管理實時數據:使用 React 的狀態管理(useState、useEffect)來處理實時更新的數據。
  • 展示實時更新的內容:將從 WebSocket 接收到的數據即時展示在頁面上。

index.js跟上篇一樣不用動

server.js

// server.js
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 8080 });

// 當有客戶端連接時觸發
wss.on("connection", (ws) => {
    console.log("客戶端已連接");

    // 定時向客戶端發送消息
    const sendCurrentTime = setInterval(() => {
        const message = `服務器時間:${new Date().toLocaleTimeString()}`;
        ws.send(message);
    }, 1000);

    // 處理客戶端發來的消息
    ws.on("message", (message) => {
        console.log("收到客戶端消息:", message.toString());
    });

    // 當連接關閉時清除定時器
    ws.on("close", () => {
        console.log("客戶端已斷開連接");
        clearInterval(sendCurrentTime);
    });
});

console.log("WebSocket 服務器運行在 ws://localhost:8080");

App.jsx

import React, { useState, useEffect, useRef } from 'react';

function App() {
  const [serverTime, setServerTime] = useState('');
  const ws = useRef(null);
  const [clientmessage,setmessage]=useState('');
  useEffect(() => {
    // 建立 WebSocket 連接
    ws.current = new WebSocket('ws://localhost:8080');

    // 當 WebSocket 連接成功時
    ws.current.onopen = () => {
      console.log('WebSocket 連接成功');
    };

    // 當收到服務器消息時
    ws.current.onmessage = (event) => {
      console.log('收到服務器消息:', event.data);
      setServerTime(event.data); // 更新服務器時間
    };

    // 當 WebSocket 連接關閉時
    ws.current.onclose = () => {
      console.log('WebSocket 連接關閉');
    };

    // 當 WebSocket 出現錯誤時
    ws.current.onerror = (error) => {
      console.error('WebSocket 錯誤:', error);
    };

    // 組件卸載時關閉 WebSocket 連接
    return () => {
      if (ws.current) {
        ws.current.close();
      }
    };
  }, []);

  // 發送消息到服務器
  const sendMessage = () => {
    if (ws.current && ws.current.readyState === WebSocket.OPEN) {
      ws.current.send(`${clientmessage}`);
    }
  };

  return (
    <div style={{ textAlign: 'center', marginTop: '50px' }}>
      <h1>實時服務器時間</h1>
      <h2>{serverTime}</h2>
      <input type="text" value={clientmessage} onChange={(e)=>setmessage(e.target.value)}  />
      <button onClick={sendMessage}>發送消息到服務器</button>
    </div>
  );
}

export default App;

結尾

從這個簡單的時鐘範例可以看出,當前端需要頻繁地從後端獲取數據進行實時渲染時,WebSocket 比起 HTTP API 更加高效,因為它提供了持久的雙向連接,允許服務器主動推送數據給客戶端,而無需客戶端每次都發出請求。這樣的方式能夠提供更低的延遲和更好的用戶體驗。

如果你要做股票的監控將後端搜索到的資料渲染到前端WebSocket絕對是最好的選擇之一。

https://ithelp.ithome.com.tw/upload/images/20241005/20162004VMMGP7gIkp.png

如果你的console.log有問題,可以看上篇有解釋,這邊簡單說一下是因為<React.StrictMode>的雙重渲染導致,但對網頁是沒有影響的
https://ithelp.ithome.com.tw/upload/images/20241005/20162004SeVol4Hwsa.png!


上一篇
[day26]WebSocket 與 React 基礎:建立 WebSocket 連接
下一篇
[day28]WebSocket 與 React 使用者對話
系列文
雙向奔赴的websocket與冰冷的react30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言